import os
import sqlite3
import hashlib
import zipfile
from pathlib import Path
from datetime import datetime
import sys

# 注册datetime适配器和转换器
def adapt_datetime(ts):
    return ts.isoformat()

def convert_datetime(s):
    return datetime.fromisoformat(s.decode('utf-8'))

sqlite3.register_adapter(datetime, adapt_datetime)
sqlite3.register_converter("DATETIME", convert_datetime)

def create_db(db_path):
    conn = sqlite3.connect(db_path, detect_types=sqlite3.PARSE_DECLTYPES)
    cursor = conn.cursor()
    
    # 创建表结构，注意create_time字段类型为DATETIME
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS photo_hash (
            id INTEGER PRIMARY KEY,
            zip_path TEXT NOT NULL,
            zip_name TEXT NOT NULL,
            file_path TEXT NOT NULL,
            file_name TEXT NOT NULL,
            file_hash TEXT NOT NULL,
            create_time DATETIME NOT NULL
        )
    ''')
    # 清空表数据
    cursor.execute('DELETE FROM photo_hash')
    conn.commit()
    return conn

def calculate_file_hash(file_content):
    """计算给定文件内容的SHA256哈希值"""
    sha256_hash = hashlib.sha256()
    sha256_hash.update(file_content)
    return sha256_hash.hexdigest()

def scan_and_store_files(directory):
    db_path = str(Path(directory) / 'file_hashes.db')
    conn = create_db(db_path)
    cursor = conn.cursor()
    
    base_dir = Path(directory)
    for zip_path in base_dir.rglob('*.zip'):
        try:
            print(f"正在处理ZIP文件: {zip_path}")
            with zipfile.ZipFile(zip_path, 'r') as archive:
                relative_zip_path = str(zip_path.relative_to(base_dir).parent)  # 只获取ZIP文件的相对路径，不包括文件名
                zip_name = zip_path.name
                for file_info in archive.infolist():
                    if not file_info.is_dir():  # 只检查是否为目录
                        with archive.open(file_info) as file:
                            file_content = file.read()
                            file_hash = calculate_file_hash(file_content)
                            # 提取文件名，不包括路径
                            just_filename = Path(file_info.filename).name
                            
                            # 检查哈希是否已存在于photo_hash表中
                            cursor.execute("SELECT COUNT(*) FROM photo_hash WHERE file_hash=?", (file_hash,))
                            if cursor.fetchone()[0] > 0:
                                print(f"文件哈希 {file_hash} 已存在，{just_filename} in {zip_name}")
                                continue
                            
                            current_time = datetime.now()  # 使用datetime对象
                            
                            cursor.execute('''
                                INSERT INTO photo_hash (zip_path, zip_name, file_path, file_name, file_hash, create_time)
                                VALUES (?, ?, ?, ?, ?, ?)
                            ''', (
                                relative_zip_path,  # 使用ZIP文件的相对路径（不包括文件名）
                                zip_name,
                                str(Path(file_info.filename).parent),
                                just_filename,  # 使用仅文件名
                                file_hash,
                                current_time  # 直接插入datetime对象
                            ))
        except Exception as e:
            print(f"处理ZIP文件 {zip_path} 时出错: {e}")
            continue
    
    conn.commit()
    conn.close()

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("使用方法: python photo_scan.py <directory>")
        sys.exit(1)

    directory = sys.argv[1]
    if not os.path.isdir(directory):
        print(f"错误: {directory} 不是一个有效的目录")
        sys.exit(1)
    
    scan_and_store_files(directory)